class EventPositionController {

  def index = { redirect(controller:'event',action:'futureEvents') }

  // the delete, save and update actions only accept POST requests
  static allowedMethods = [save: 'POST', update: 'POST']

  def confirmation = {
    def event = Event.get(params.eventId)
    def position = EventPosition.get(params.id)

    if (!position) {
      flash.message = "Event Position not found with id ${params.id}"
      redirect(controller:'event',action:'futureEvents')
    }
    else { return [eventPositionInstance: position, eventInstance: event] }
  }

  def delete = {
    def eventPositionInstance = EventPosition.get(params.id)
    def eventInstance = Event.get(params.eventId)
    if (eventPositionInstance) {
      def positionName = eventPositionInstance.name
      try {
        eventInstance.removeFromPositions(eventPositionInstance)
        eventPositionInstance.delete()
        flash.message = "Position ${positionName} deleted from ${eventInstance.name}"
        redirect(controller: 'event', action: 'edit', id: params.eventId)
      }
      catch (org.springframework.dao.DataIntegrityViolationException e) {
        flash.message = "Position ${positionName} could not be deleted"
        redirect(controller: 'event', action: 'edit', id: params.eventId)
      }
    }
    else {
      flash.message = "Position not found with id ${params.id}"
      redirect(controller: 'event', action: 'edit', id: params.eventId)
    }
  }

  def signup = {
    def position = EventPosition.get(params.id)
    def volunteer = Volunteer.get(session.volunteer.id)

    if (position.volunteers.size() >= position.numberOfVolunteers) {
      flash.message = "Position ${position.name} is full"
      redirect(controller: 'event', action: 'show', id: params.eventId)
      return
    }

    if (position.volunteers.contains(volunteer)) {
      flash.message = "You've already signed up for position ${position.name}"
      redirect(controller: 'event', action: 'show', id: params.eventId)
      return
    }

    position.addToVolunteers(volunteer);
    flash.message = "Thank you for signing up for ${position.name} position"
    redirect(action: 'confirmation', id: params.id, params: [eventId: params.eventId])
  }

  def removeVolunteer = {
    def position = EventPosition.get(params.positionId)
    def volunteer = Volunteer.get(params.id)
    position.removeFromVolunteers(volunteer).save(flush:true)
    flash.message = "Volunteer ${volunteer.firstName} ${volunteer.lastName} removed from position"
    redirect(action: 'edit', id: params.positionId, params: [eventId: params.eventId])
  }

  def edit = {
    def position = EventPosition.get(params.id)
    def event = Event.get(params.eventId)

    if (session.volunteer.id != event.owner.id) {
      flash.message = "You can only edit your own event positions."
      redirect(controller: 'event', action: 'myEvents')
      return
    }

    if (!position) {
      flash.message = "Event Position not found with id ${params.id}"
      redirect(controller: 'event', action: 'futureEvents')
    }
    else {
      return [eventPositionInstance: position, eventInstance: event]
    }
  }

  def update = {
    def eventPositionInstance = EventPosition.get(params.id)
    if (eventPositionInstance) {
      if (params.version) {
        def version = params.version.toLong()
        if (eventPositionInstance.version > version) {

          eventPositionInstance.errors.rejectValue("version", "eventPosition.optimistic.locking.failure", "Another user has updated this EventPosition while you were editing.")
          render(view: 'edit', model: [eventPositionInstance: eventPositionInstance])
          return
        }
      }
      eventPositionInstance.properties = params
      def eventInstance = Event.get(params.eventId)
      eventPositionInstance.validate()
      validatePosition(eventPositionInstance, eventInstance)

      if (!eventPositionInstance.hasErrors() && eventPositionInstance.save()) {
        flash.message = "EventPosition ${eventPositionInstance.name} updated"
        redirect(controller: 'event', action: 'edit', id: params.eventId)
      }
      else {
        render(view: 'edit', model: [eventPositionInstance: eventPositionInstance, eventInstance: eventInstance])
      }
    }
    else {
      flash.message = "EventPosition not found with id ${params.id}"
      redirect(action: edit, id: params.id)
    }
  }

  def create = {
    def eventPositionInstance = new EventPosition()
    eventPositionInstance.properties = params
    def eventInstance = Event.get(params.id)
    return ['eventInstance': eventInstance, 'eventPositionInstance': eventPositionInstance]
  }

  def save = {
    def eventPositionInstance = new EventPosition(params)
    def eventInstance = Event.get(params.id)

    eventPositionInstance.validate()
    validatePosition(eventPositionInstance, eventInstance)

    if (!eventPositionInstance.hasErrors()) { // && eventPositionInstance.save()) {
      eventInstance.addToPositions(eventPositionInstance).save(flush: true)
      flash.message = "Event Position '${eventPositionInstance.name}' created"
      redirect(controller: 'event', action: 'edit', id: params.id)
    }
    else {
      render(view: 'create', model: [eventPositionInstance: eventPositionInstance, eventInstance: eventInstance])
    }
  }

  private def validatePosition(EventPosition eventPositionInstance, eventInstance) {
// validate the dates for the position:
    if (eventPositionInstance.startDate != null) {
      if (eventPositionInstance.startDate.before(eventInstance.startDate) ||
              eventPositionInstance.startDate.after(eventInstance.endDate)) {
        eventPositionInstance.errors.rejectValue("startDate", "eventPosition.startDate.validation.failure", "EventPosition startDate must be within event dates.")
      }
    }
    if (eventPositionInstance.endDate != null) {
      if (eventPositionInstance.endDate.before(eventPositionInstance.startDate)) {
        eventPositionInstance.errors.rejectValue("endDate", "eventPosition.endDate.validation.failure", "EventPosition endDate must be later than event position start date.")
      }
      if (eventPositionInstance.endDate.before(eventInstance.startDate) ||
              eventPositionInstance.endDate.after(eventInstance.endDate)) {
        eventPositionInstance.errors.rejectValue("endDate", "eventPosition.endDate.validation.failure", "EventPosition endDate must be within event dates.")
      }
    }
  }


}
